#include "shm.h"
union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int sem_id = -1;

int mode = MANUAL_MODE;
void *shm_addr = NULL;
int shmid;

struct sembuf sem_p = {0, -1, 0};
struct sembuf sem_v = {0, 1, 0};

// P操作
static int P()
{
    return semop(sem_id, &sem_p, 1);
}

// V操作
static int V()
{
    return semop(sem_id, &sem_v, 1);
}
void shm_init()
{
	//打开一个信号量集，该信号量集只有一个信号量
    sem_id = semget((key_t) SIGNAL_KEY, 1, IPC_CREAT | 0666);
    if (sem_id == -1)
    {
        perror("semget error!");
        exit(1);
    }

 	// 使用约定的键值打开共享内存
    shmid = shmget((key_t) SHARE_KEY, SHM_BUF_SIZE,  0666 | IPC_CREAT);
    //printf("shmid : %u\n", shmid);
    if (shmid < 0)
    {
        perror("shmget error!");
        exit(1);
    }

    // 将共享内存附加到本进程
    shm_addr = shmat(shmid, NULL, 0);
    if (shm_addr == (void *) -1)
    {
        perror("shmat error!");
        exit(1);
    }  
}
int shm_read()
{     
    // 准备进入临界区
	if (P() == -1)
    {
        printf("P error!\n");
        exit(1);
    }
    // 在临界区里面,读取数据
    char tmp[SHM_BUF_SIZE];
    bzero(tmp, SHM_BUF_SIZE);
    memcpy(tmp, shm_addr, SHM_BUF_SIZE);
    
    if ('m' == tmp[0])
    {
		mode = MANUAL_MODE;
    }
    else
    {
		mode = AUTO_MODE;
    }

    // 离开临界区
    if (V() == -1)
    {
        printf("V error!\n");
        exit(1);
    }
    // 分离
    //if (shmdt(shm_addr) == -1)
    //{
    //    printf("shmdt error!\n");
    //    exit(1);
    //}

    // 删除共享内存
    /*if (shmctl(shmid, IPC_RMID, 0) == -1)
    {
        printf("shmctl error!\n");
        exit(1);
    }*/
	return mode;
}
